package com.codi.api.controller.h5;

import com.codi.base.log.annotation.Loggable;
import com.codi.base.util.DateUtil;
import com.codi.base.util.EqualsUtil;
import com.codi.base.util.MD5;
import com.codi.base.util.StringUtil;
import com.codi.base.web.RequestUtils;
import com.codi.base.web.ResponseUtils;
import com.codi.bus.constant.GlobalConstant;
import com.codi.bus.core.domain.User;
import com.codi.bus.core.domain.UserBank;
import com.codi.bus.core.jwt.Jwt;
import com.codi.bus.core.resultModel.AssetsResult;
import com.codi.bus.core.resultModel.BaseResult;
import com.codi.bus.core.resultModel.PaperInfoTestResult;
import com.codi.bus.core.service.*;
import com.codi.bus.core.util.BaseResultUtil;
import com.codi.message.constant.ErrorConstant;
import com.codi.message.util.MessageUtil;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Author: zengxl
 * @Description: 用户相关控制类
 * @Date:2018/3/8 13:49
 */
@RestController
@Slf4j
@RequestMapping("/h5/user")
public class H5UserController {
    @Autowired
    private RedisTemplate<String, String> stringRedisTemplate;
    @Resource
    private UserService userService;
    @Autowired
    private BankService bankService;
    @Autowired
    private QueryService queryService;
    @Autowired
    private PaperInfoService paperInfoService;
    @Autowired
    private H5Service h5Service;
    /**
     * 用户是否开户
     *
     * @param request
     * @return
     */
    @GetMapping("/isOpen")
    public BaseResult isOpen(HttpServletRequest request) {
        BaseResult result = new BaseResult();
        Long userId = Long.valueOf(RequestUtils.getHeader(request, "userid"));
        User user = userService.getUser(userId);
        BaseResultUtil.isOpen(result, user);
        return result;
    }
    @PostMapping("/login")
    @Loggable
    public BaseResult login(@RequestParam String phone,@RequestParam String passwd,
                                      @RequestParam String channelCode,@RequestParam String redirectType) {
        BaseResult result = new BaseResult();
        result.setSuccess(false);
        if (StringUtil.isEmpty(phone)) {
            result.setErrorCode(ErrorConstant.ERROR_FIELD_NO_FIND);
            result.setErrorMessage(MessageUtil.getErrorMessage(ErrorConstant.ERROR_FIELD_NO_FIND,
                ErrorConstant.PLACEHOLDER_FIELD_NO_FIND_FIELD, "手机号"));
            return result;
        }

        if (StringUtil.isEmpty(passwd)) {
            result.setErrorCode(ErrorConstant.ERROR_FIELD_NO_FIND);
            result.setErrorMessage(MessageUtil.getErrorMessage(ErrorConstant.ERROR_FIELD_NO_FIND,
                ErrorConstant.PLACEHOLDER_FIELD_NO_FIND_FIELD, "密码"));
            return result;
        }
        if (StringUtil.isEmpty(channelCode)) {
            result.setErrorCode(ErrorConstant.ERROR_FIELD_NO_FIND);
            result.setErrorMessage(MessageUtil.getErrorMessage(ErrorConstant.ERROR_FIELD_NO_FIND,
                ErrorConstant.PLACEHOLDER_FIELD_NO_FIND_FIELD, "渠道来源编号"));
            return result;
        }
        if (StringUtil.isEmpty(redirectType)) {
            result.setErrorCode(ErrorConstant.ERROR_FIELD_NO_FIND);
            result.setErrorMessage(MessageUtil.getErrorMessage(ErrorConstant.ERROR_FIELD_NO_FIND,
                ErrorConstant.PLACEHOLDER_FIELD_NO_FIND_FIELD, "跳转类型"));
            return result;
        }

        BaseResult loginResult = userService.h5Login(phone,passwd);
        if(loginResult.getSuccess()){
            Map<String, Object> returnMap = Maps.newHashMap();
            int status = -1;
            User user = (User)loginResult.getResult();

            String externalClientId = user.getExternalClientId();
            if (StringUtil.isEmpty(externalClientId)) {
                //未开户
                status = 1;
            }else{
                List<UserBank> userBanks = bankService.getListByUserId(user.getUserId());
                if (userBanks == null || userBanks.size() == 0) {
                    //未开户
                    status = 1;
                }else{
                    boolean isOpen = false;
                    for (UserBank bankModel : userBanks) {
                        if (!StringUtil.isEmpty(bankModel.getCapitalMode()) && !bankModel.getCapitalMode().equals(GlobalConstant.CAPITAL_MODE_COUNTER)) {
                            isOpen = true;
                            break;
                        }
                    }
                    if (!isOpen) {
                        //未开户
                        status = 1;
                    }else{
                        //判断是否已在私募入口做过风险测评，如果已做过，则传入之前的风险测评结果
                        PaperInfoTestResult privateResult = paperInfoService.getUserPaperInfoTestResult(user.getUserId(), "",null);
                        if (!privateResult.isHave_tested()) {
                            //未做风险评测
                            status = 2;
                        }else{
                            String expireDate = privateResult.getExpire_date();
                            Date now = new Date();
                            Date expire = null;
                            try {
                                expire = DateUtil.parse(expireDate);
                                if (now.after(expire)) {
                                    //风险评测过期
                                    status = 3;
                                }else{
                                    //正常
                                    status = 0;
                                }
                            } catch (Exception e) {
                                status = 3;
                            }

                        }
                    }
                }
            }
            if(status == -1){
                result.setErrorType(GlobalConstant.ERROR_TYPE_APPLICATION);
                result.setErrorCode(ErrorConstant.ERROR_NOT_LOGIN);
                result.setSuccess(false);
                result.setErrorMessage("用户开户状态获取失败");
                log.error("接口：/h5/user/login,用户开户状态获取失败");
                return result;
            }
            Date date = new Date();
            Map<String, Object> payload = new HashMap<String, Object>();
            payload.put("uid", String.valueOf(user.getUserId()));// 用户id
            payload.put("iat", date.getTime());// 生成时间:当前
            payload.put("ext", date.getTime() + GlobalConstant.H5_TOKEN_ACTIVE_TIME);// 过期时间
            String h5Token = Jwt.createToken(payload);
            stringRedisTemplate.opsForValue().set(GlobalConstant.H5 + "_" + channelCode + "_token_" + user.getUserId(), h5Token, GlobalConstant.H5_TOKEN_ACTIVE_TIME, TimeUnit.MILLISECONDS);
            //验证成功后，返回数据需要包含请求头信息。
            returnMap.put("channelCode", channelCode);
            returnMap.put("userId", user.getUserId());
            returnMap.put("token", h5Token);
            returnMap.put("redirectType",redirectType);
            String totalAsset = "";
            if(status != 1){
                AssetsResult assets = queryService.queryAssets(user.getUserId());
                if(assets.getTotalWorthValueString() != null){
                    totalAsset = assets.getTotalWorthValueString();
                }
            }
            returnMap.put("totalAsset",totalAsset);
            returnMap.put("status",status);
            Boolean isChinaTax = user.getIsChinaTax() != null ? user.getIsChinaTax():false;
            returnMap.put("isChinaTax",isChinaTax);
            result.setSuccess(true);
            result.setResult(returnMap);
            return result;
        }else{
            result.setErrorMessage(loginResult.getErrorMessage());
            return result;
        }
    }
    @PostMapping("/register")
    @Loggable
    public BaseResult register(@RequestParam String phone,@RequestParam String passwd,
                            @RequestParam String channelCode,@RequestParam String verCode) {
        BaseResult result = new BaseResult();
        result.setSuccess(false);
        if (StringUtil.isEmpty(phone)) {
            result.setErrorCode(ErrorConstant.ERROR_FIELD_NO_FIND);
            result.setErrorMessage(MessageUtil.getErrorMessage(ErrorConstant.ERROR_FIELD_NO_FIND,
                ErrorConstant.PLACEHOLDER_FIELD_NO_FIND_FIELD, "手机号"));
            return result;
        }

        if (StringUtil.isEmpty(passwd)) {
            result.setErrorCode(ErrorConstant.ERROR_FIELD_NO_FIND);
            result.setErrorMessage(MessageUtil.getErrorMessage(ErrorConstant.ERROR_FIELD_NO_FIND,
                ErrorConstant.PLACEHOLDER_FIELD_NO_FIND_FIELD, "密码"));
            return result;
        }
        if (StringUtil.isEmpty(channelCode)) {
            result.setErrorCode(ErrorConstant.ERROR_FIELD_NO_FIND);
            result.setErrorMessage(MessageUtil.getErrorMessage(ErrorConstant.ERROR_FIELD_NO_FIND,
                ErrorConstant.PLACEHOLDER_FIELD_NO_FIND_FIELD, "渠道来源编号"));
            return result;
        }
        if (StringUtil.isEmpty(verCode)) {
            result.setErrorCode(ErrorConstant.ERROR_FIELD_NO_FIND);
            result.setErrorMessage(MessageUtil.getErrorMessage(ErrorConstant.ERROR_FIELD_NO_FIND,
                ErrorConstant.PLACEHOLDER_FIELD_NO_FIND_FIELD, "验证码"));
            return result;
        }
        String confirmVerCode = stringRedisTemplate.opsForValue().get("fund_h5_sms_1_" + phone);
        if (StringUtils.isEmpty(confirmVerCode)) {
            log.warn("验证码失效");
            result.setErrorMessage("验证码失效");
            return result;
        }
        if (!EqualsUtil.equalsTrim(verCode, confirmVerCode)) {
            log.warn("输入的验证码不正确");
            result.setErrorMessage("输入的验证码不正确");
            return result;
        }
        boolean flag = userService.checkMobile(phone);
        if(flag){
            log.warn("手机号码已经存在");
            result.setErrorMessage("手机号码已经存在");
            return result;
        }
        User user  = new User();
        user.setUserMobile(phone);
        user.setUserName(phone);
        user.setLoginPassword(MD5.MD5Encode(passwd));
        user.setUserState(1);//1:注册、2：绑卡
        user.setCreateDate(new Date());
        user.setIsValid(true);
        user.setIsOrg(false);
        user.setUserFrom(channelCode);
        user = h5Service.addUserByH5(user);
        if (user.getUserId() <= 0) {
            result.setErrorType(GlobalConstant.ERROR_TYPE_APPLICATION);
            result.setErrorCode(ErrorConstant.ERROR_NOT_LOGIN);
            result.setErrorMessage("用户未在基金系统注册,自动注册失败!");
            log.error("接口：/h5/index,用户未在基金系统注册,自动注册失败");
            return result;
        }
        Map<String, Object> returnMap = Maps.newHashMap();
        Date date = new Date();
        Map<String, Object> payload = new HashMap<String, Object>();
        payload.put("uid", String.valueOf(user.getUserId()));// 用户id
        payload.put("iat", date.getTime());// 生成时间:当前
        payload.put("ext", date.getTime() + GlobalConstant.H5_TOKEN_ACTIVE_TIME);// 过期时间
        String h5Token = Jwt.createToken(payload);
        stringRedisTemplate.opsForValue().set(GlobalConstant.H5 + "_" + channelCode + "_token_" + user.getUserId(), h5Token, GlobalConstant.H5_TOKEN_ACTIVE_TIME, TimeUnit.MILLISECONDS);
        //验证成功后，返回数据需要包含请求头信息。
        returnMap.put("channelCode", channelCode);
        returnMap.put("userId", user.getUserId());
        returnMap.put("token", h5Token);
        returnMap.put("status","1");
        Boolean isChinaTax = user.getIsChinaTax() != null ? user.getIsChinaTax():false;
        returnMap.put("isChinaTax",isChinaTax);
        result.setSuccess(true);
        result.setResult(returnMap);
        stringRedisTemplate.delete("fund_h5_sms_1_" + phone);
        return result;
    }

    @PostMapping("/resetPassword")
    @Loggable
    public BaseResult resetPassword(@RequestParam String phone,@RequestParam String newPasswd,@RequestParam String verCode) {
        BaseResult result = new BaseResult();
        result.setSuccess(false);
        if (StringUtil.isEmpty(phone)) {
            result.setErrorCode(ErrorConstant.ERROR_FIELD_NO_FIND);
            result.setErrorMessage(MessageUtil.getErrorMessage(ErrorConstant.ERROR_FIELD_NO_FIND,
                ErrorConstant.PLACEHOLDER_FIELD_NO_FIND_FIELD, "手机号"));
            return result;
        }

        if (StringUtil.isEmpty(newPasswd)) {
            result.setErrorCode(ErrorConstant.ERROR_FIELD_NO_FIND);
            result.setErrorMessage(MessageUtil.getErrorMessage(ErrorConstant.ERROR_FIELD_NO_FIND,
                ErrorConstant.PLACEHOLDER_FIELD_NO_FIND_FIELD, "新密码"));
            return result;
        }
        if (StringUtil.isEmpty(verCode)) {
            result.setErrorCode(ErrorConstant.ERROR_FIELD_NO_FIND);
            result.setErrorMessage(MessageUtil.getErrorMessage(ErrorConstant.ERROR_FIELD_NO_FIND,
                ErrorConstant.PLACEHOLDER_FIELD_NO_FIND_FIELD, "验证码"));
            return result;
        }
        String confirmVerCode = stringRedisTemplate.opsForValue().get("fund_h5_sms_2_" + phone);
        if (StringUtils.isEmpty(confirmVerCode)) {
            log.warn("验证码失效");
            result.setErrorMessage("验证码失效");
            return result;
        }
        if (!EqualsUtil.equalsTrim(verCode, confirmVerCode)) {
            log.warn("输入的验证码不正确");
            result.setErrorMessage("输入的验证码不正确");
            return result;
        }
        User user = userService.getUser(phone);
        if (user == null || user.getUserId() <= 0) {
            result.setErrorMessage("用户不存在");
            return result;
        }
        user.setLoginPassword(MD5.MD5Encode(newPasswd));
        userService.update(user);
        result.setSuccess(true);
        result.setResult(user);
        stringRedisTemplate.delete("fund_h5_sms_2_" + phone);
        return result;
    }

}
